#ifndef COMMANDS_H
#define COMMANDS_H

#include "line.h"
#include "model.h"
#include "view.h"
#include <QGraphicsItem>

class AddItemCmd : public QUndoCommand {
public:
    AddItemCmd(Model* model,QGraphicsItem* item):m_model(model),m_item(item){
        setText("Create item");
    }
    virtual void undo(){
        m_model->removeItem(m_item);
    }
    virtual void redo(){
        m_item->setFlag(QGraphicsItem::ItemIsSelectable);
        m_model->addItem(m_item);
    }
    ~AddItemCmd(){ delete m_item; }
private:
    Model* m_model;
    QGraphicsItem* m_item;
};

class ChangeZoomCmd : public QUndoCommand {
public:
    ChangeZoomCmd(View* view, QRectF to):m_view(view),m_to(to) {
        setText("Change Zoom");
    }
    virtual void undo(){
        m_view->fitInView(m_from, Qt::KeepAspectRatio);
    }
    virtual void redo(){
        QPoint a1(m_view->rect().x(),m_view->rect().y());
        QPoint a2(m_view->rect().x()+m_view->rect().width(),m_view->rect().y()+m_view->rect().height());
        QPointF b1 = m_view->mapToScene(a1);
        QPointF b2 = m_view->mapToScene(a2);
        m_from.setRect(b1.x(),b1.y(),b2.x()-b1.x(),b2.y()-b1.y());
        m_view->fitInView(m_to, Qt::KeepAspectRatio);
    }
    ~ChangeZoomCmd(){ }
private:
    View* m_view;
    QRectF m_to;
    QRectF m_from;
};


class MoveCmd : public QUndoCommand {
public:
    MoveCmd(Model* model,QList<QGraphicsItem*> items, qreal dx, qreal dy):m_model(model),m_items(items),m_dx(dx),m_dy(dy){
        m_first=true;
        setText("Move item");
    }
    virtual void undo(){
        for(QList<QGraphicsItem*>::iterator it=m_items.begin();it!=m_items.end();++it)
            (*it)->setPos((*it)->x()-m_dx,(*it)->y()-m_dy);
    }
    virtual void redo(){
        if(!m_first){
            for(QList<QGraphicsItem*>::iterator it=m_items.begin();it!=m_items.end();++it)
                (*it)->setPos((*it)->x()+m_dx,(*it)->y()+m_dy);

        } else {
            m_first = false;
        }
    }
    ~MoveCmd(){  }
private:
    Model* m_model;
    bool m_first;
    qreal m_dx,m_dy;
    QList<QGraphicsItem*> m_items;
};

class EraseCmd : public QUndoCommand {
public:
    EraseCmd(Model* model,QList<QGraphicsItem*> items):m_model(model),m_items(items){
        setText("Move item");
    }
    virtual void undo(){
        for(QList<QGraphicsItem*>::iterator it = m_items.begin();it!=m_items.end();++it){
            m_model->addItem(*it);
        }
    }
    virtual void redo(){
        for(QList<QGraphicsItem*>::iterator it = m_items.begin();it!=m_items.end();++it){
            m_model->removeItem(*it);
        }
    }
    ~EraseCmd(){  }
private:
    Model* m_model;
    QList<QGraphicsItem*> m_items;
};

#endif // COMMANDS_H
